using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Web.Security;
using System.Xml;
using System.Xml.Serialization;
using System.Runtime.CompilerServices;
using System.Security.Permissions;

namespace Artem.Web.Security.Store {

    /// <summary>
    /// 
    /// </summary>
    public partial class XmlRoleStore : Persistable<List<XmlRole>> {

        #region Properties  /////////////////////////////////////////////////////////////

        /// <summary>
        /// Gets the roles.
        /// </summary>
        /// <value>The roles.</value>
        public virtual List<XmlRole> Roles {
            get { return base.Value ?? (base.Value = new List<XmlRole>()); }
        }
        #endregion

        #region Construct  //////////////////////////////////////////////////////////////

        /// <summary>
        /// Initializes a new instance of the <see cref="XmlRoleStore"/> class.
        /// </summary>
        /// <param name="fileName">Name of the file.</param>
        public XmlRoleStore(string fileName)
            : base(fileName) {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="XmlRoleStore"/> class.
        /// </summary>
        protected XmlRoleStore()
            : base(null) {
        }
        #endregion

        #region Methods /////////////////////////////////////////////////////////////////

        /// <summary>
        /// Gets the role.
        /// </summary>
        /// <param name="roleName">Name of the role.</param>
        /// <returns></returns>
        public virtual XmlRole GetRole(string roleName) {

            lock (SyncRoot) {
                return (Roles != null)
                    ? Roles.Find(delegate(XmlRole role) { return role.Name.Equals(roleName, StringComparison.OrdinalIgnoreCase); })
                    : null;
            }
        }

        /// <summary>
        /// Gets the roles for user.
        /// </summary>
        /// <param name="userName">Name of the user.</param>
        /// <returns></returns>
        public virtual List<XmlRole> GetRolesForUser(string userName) {

            lock (SyncRoot) {
                List<XmlRole> results = new List<XmlRole>();
                List<XmlRole> roles = this.Roles;
                if (roles != null) {
                    foreach (XmlRole r in roles) {
                        if (r.Users.Contains(userName))
                            results.Add(r);
                    }
                }
                return results;
            }
        }

        /// <summary>
        /// Gets the users in role.
        /// </summary>
        /// <param name="roleName">Name of the role.</param>
        /// <returns></returns>
        public virtual string[] GetUsersInRole(string roleName) {

            lock (SyncRoot) {
                XmlRole role = GetRole(roleName);
                if (role != null) {
                    string[] Results = new string[role.Users.Count];
                    role.Users.CopyTo(Results, 0);
                    return Results;
                }
                else
                    throw new Exception(string.Format("Role with name {0} does not exist!", roleName));
            }
        }
        #endregion
    }
}
